﻿using System;
using System.Collections.Generic;
using System.Linq;
using Ext.Net;
using KamLib.Ext.Net.Handlers;

namespace KamLib.Controls
{


    public class UilViewPartGridPanel : GridPanel, IUilViewPart
    {
        public UilController Controller { get; set; }
        public string ViewID { get; set; }
        string IUilViewPart.Name { get { return ViewID; } }
        public IList<IUilViewPart> Parts { get; set; }

        public string KeyField { get; set; }
        public string GroupField { get; set; }
        public string SortField { get; set; }
        public SortDirection? SortDir { get; set; }

        public bool? CanInsert { get; set; }
        public bool? CanEdit { get; set; }
        public bool? CanDelete { get; set; }
        public bool? IsLocal { get; set; }
        public int? PageSize { get; set; }

        public IEnumerable<UilAction> Actions;

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            UilViewPartHelper.RegisterAsPart(this);
        }

        public virtual void AdaptToController()
        {
            Actions = Controller.GetActions(this);

            var source = Controller as IUilEntitiesSource;
            if (source == null) return;

            if (KeyField == null && source.KeyFields != null) KeyField = source.KeyFields.FirstName();
            if (GroupField == null && source.GroupFields != null) GroupField = source.GroupFields.FirstName();
            if (SortField == null && source.SortFields != null)
            {
                var field = source.SortFields.FirstOrDefault();
                if (field != null)
                {
                    SortField = field.Name;
                    SortDir = GridPanelHandler.FromUilType(field.SortDir);
                }
            }

            if (CanInsert == null) CanInsert = source.CanInsert;
            if (CanEdit == null) CanEdit = source.CanEdit;
            if (CanDelete == null) CanDelete = source.CanDelete;
            if (IsLocal == null) IsLocal = source.IsLocal;
            if (PageSize == null) PageSize = source.PageSize;

            PreRender += (sender, ee) =>
            {
                var store = Store.Primary;
                if (store == null) return;

                store.BaseParams.AddRaw("key", "Ext.encode({ ctid: '" + Controller.Key.CTID + "' })");
                store.BaseParams.AddValue("name", "ext.grid.GetData");
                store.BaseParams.AddRaw("args", "{}");

                if (store.Proxy.Count == 0)
                {
                    store.Proxy.Add(new HttpProxy
                    {
                        Json = true,
                        Url = "~/UilService.asmx/Handle",
                        Headers = { new Parameter("X-Ext.Net", "delta=true") }
                    });
                }
            };

        }
    }



    public class Grid : UilViewPartGridPanel
    {


        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            GetPropsFromColumns();
            SetProps1();

            var store = AddStore1();
            AddJsonReader1(store);
            AddColumnFilters();
            //AddFieldsByColumns(reader);

            AddColumns1();
            AddToolbars1();
        }

        private void GetPropsFromColumns()
        {
            foreach (var col in ColumnModel.Columns.OfType<Column>())
            {
                if (col.IsKey) KeyField = col.Name;
                if (col.Expanded) AutoExpandColumn = col.Name;
            }
        }


        protected void SetProps1()
        {
            StripeRows = true;
            TrackMouseOver = true;
            LoadMask.ShowMask = true;
            SaveMask.ShowMask = true;

            if (SelectionModel.Count == 0)
                SelectionModel.Add(new RowSelectionModel { SingleSelect = true });
        }

        protected void AddColumns1()
        {

            GridCommand col1 = null, col2 = null;
            MenuCommand col3 = null;

            if (ClicksToEdit == 2 && CanEdit == true)
            {
                col1 = new GridCommand
                {
                    IconCls = "icon-form_yellow_edit-16",
                    Text = "Edit",
                    CommandName = "edit",
                };
                col1.ToolTip.Text = "Edit";
            }
            else if (ClicksToEdit == 1 && CanEdit == true)
            {
                foreach (var col in ColumnModel.Columns)
                {
                    if (col.Editor.Count > 0) continue;
                    var cf = col as IColumnEditorFactory;
                    if (cf != null)
                        col.Editor.Add(cf.NewEditor());
                }
            }

            if (CanDelete == true)
            {
                col3 = new MenuCommand
                {
                    Text = "Delete",
                    IconCls = "icon-delete2-16",
                    HideOnClick = false,
                };
                col3.Menu.Items.Add(new MenuCommand
                {
                    Text = "Delete", // + c.EntityDesc.Name,
                    CommandName = "delete",
                });
            }

            if (col3 != null)
            {
                col2 = new GridCommand
                {
                    IconCls = "icon-navigate_close-16",
                };
                col2.ToolTip.Text = "Row Menu";
                col2.Menu.EnableScrolling = false;
                col2.Menu.Items.Add(col3);
            }


            if (col1 == null && col2 == null) return;

            var width = 0;
            var cmdCol = new CommandColumn { MenuDisabled = true };
            if (col1 != null)
            {
                width += 46;
                cmdCol.Commands.Add(col1);
            }
            if (col2 != null)
            {
                width += 35;
                cmdCol.Commands.Add(col2);
            }
            cmdCol.Width = width;
            ColumnModel.Columns.Add(cmdCol);
        }


        protected Store AddStore1()
        {
            var store = Store.FirstOrDefault();
            if (store == null)
            {
                Store.Add(store = new Store { ID = ID + "_Store" });
            }

            //store.AutoLoad = false;
            store.RemoteSort = true;

            if (store.GroupField.isnull())
                store.GroupField = GroupField;

            if (store.SortInfo.Field.isnull())
            {
                store.SortInfo.Field = SortField.IfNull(KeyField);
                store.SortInfo.Direction = SortDir ?? SortDirection.Default;
            }

            return store;
        }


        protected DataReader AddJsonReader1(Store store)
        {
            var reader = store.Reader.FirstOrDefault();
            if (reader == null)
            {
                store.Reader.Add(reader = new JsonReader
                {
                    IDProperty = KeyField,
                    Root = "d.data",
                    TotalProperty = "d.total",
                });
            }
            return reader;
        }


        protected void AddFieldsByColumns(DataReader reader)
        {
            if (reader.Fields.Count != 0) return;

            foreach (var col in ColumnModel.Columns)
            {
                var f = new RecordField(col.DataIndex);
                var fi = col as IRecordFieldInfo;
                if (fi != null)
                    f.Type = fi.FieldType;
                reader.Fields.Add(f);
            }
        }


        protected void AddColumnFilters()
        {

            if (HideHeaders) return;

            var cols = ColumnModel.Columns.OfType<IColumnFilterFactory>().Where(a => a.Filterable).ToArray();
            if (cols.Length == 0) return;

            var filter = Plugins.OfType<GridFilters>().FirstOrDefault();
            if (filter == null)
                Plugins.Add(filter = new GridFilters { UpdateBuffer = 1000 });

            foreach (var col in cols)
            {
                var f = col.NewFilter();
                if (f != null && filter.Filters.FirstOrDefault(a => a.DataIndex == f.DataIndex) == null)
                    filter.Filters.Add(f);
            }
        }


        protected void AddToolbars1()
        {
            ToolbarBase tb = null;
            var cmps = new List<Component>();

            var local = IsLocal == true;
            var compact = ClicksToEdit == 1;

            if (!local)
            {
                tb = new PagingToolbar
                {
                    ID = ID + "_Pager",
                    PageSize = PageSize ?? 0,
                    DisplayInfo = true,
                    //DisplayMsg = "Displaying " + c.EntityDesc.Names + " {0} - {1} of {2}",
                    //EmptyMsg = "No " + c.EntityDesc.Name + " to display",
                    Height = 28,
                };
                if (!(PageSize > 0)) tb.Cls += " x-grid-hide-pager";
                if (!compact) tb.Items.Add(new ToolbarSeparator());
            }
            else if (CanInsert == true || Actions != null)
            {
                tb = new Toolbar
                {
                    ID = ID + "_TB",
                    Flat = compact,
                    Height = 28,
                };
            }

            if (Actions != null)
                cmps.AddRange(ExtUilActions.ToButtons(Actions));


            if (CanInsert == true)
            {
                //if (local)
                //{
                //    cmps.Add(new Button
                //    {
                //        IconCls = "icon-copy-16",
                //        OnClientClick = "KamLib.Logic.Grid.copyRowsToClipboard(null)",
                //        ToolTip = "Copy all rows to clipboard",
                //    });
                //    cmps.Add(new Button
                //    {
                //        IconCls = "icon-paste-16",
                //        OnClientClick = "KamLib.Logic.Grid.pasteRowsFromClipboard(" + ClientID + ")",
                //        ToolTip = "Paste rows from clipboard",
                //    });
                //}

                cmps.Add(new ToolbarFill());
                if (!local) cmps.Add(new ToolbarSeparator());

                cmps.Add(new Button
                {
                    //ID = c.Grid.ID + "_cmdAdd",
                    IconCls = "icon-add2-16",
                    Text = "Add", //+ c.EntityDesc.Name,
                    //OnClientClick = local ? "KamLib.Logic.Grid.addRow(" + ClientID + ", true)" : null,
                });
            }

            if (!(tb is PagingToolbar) && (tb == null || cmps.Count <= 0)) return;
            tb.Items.AddRange(cmps);
            TopBar.Add(tb);

            if (tb is PagingToolbar)
                CustomConfig.Add(new ConfigItem { Name = "pager", Value = tb.ClientID, Mode = ParameterMode.Value });
        }


        public string GetRefreshScript()
        {
            var pager = TopBar.OfType<PagingToolbar>().FirstOrDefault() ?? BottomBar.OfType<PagingToolbar>().FirstOrDefault();
            if (pager != null)
                return pager.ClientID + ".doRefresh();";

            var store = Store.FirstOrDefault();
            if (store != null)
                return store.ClientID + ".reload();";

            return null;
        }


        public static TabStrip MakeTabStriped(ContainerBase parent, int width, params GridPanel[] grids)
        {
            if (grids.Length < 2) return null;

            var ts = new TabStrip { Width = width };

            foreach (var grid in grids)
            {
                ts.Items.Add(new TabStripItem(grid.Title.IfNull(grid.ID))
                {
                    ActionItem = grid,
                    TabTip = grid.TabTip,
                });
                grid.Header = false;

                ToolbarBase tb;
                if (grid.TopBar.Count == 0)
                    grid.TopBar.Add(tb = new Toolbar { Height = 27 });
                else
                {
                    tb = grid.TopBar.Last();
                    if (tb.Items.OfType<ToolbarFill>().FirstOrDefault() == null)
                        tb.Items.Add(new ToolbarFill());
                    tb.Items.Add(new ToolbarSeparator { Width = 20 });
                }
                tb.Items.Add(new ToolbarSpacer(width));
            }

            parent.Items.Add(ts);
            ts.StyleSpec = "z-index:9999;position:absolute;top:4px;left:100%;margin-left:-" + width + "px;";

            return ts;
        }


    }
}
